﻿using System;
using System.Collections.Generic;
using System.Text;

namespace KoevServoAdjust
{
    public class EepromBank
    {
        //;Bank0
        //.EQU	Pgain_EE0=		int(   15*0x10000)>>8	;8.8
        //.EQU	Igain_EE0=		int(0.000*0x10000)>>0	;0.16
        //.EQU	Dgain_EE0=		int(    0*0x10000)>>8	;8.8
        //.EQU	FF1_EE0=		int(    0*0x10000)>>8	;8.4
        //.EQU	Address_EE0=			0				;4
        //.EQU	maxI_EE0=		       10				;8.0
        //.EQU	CmdMultiplier_EE0=	    4				;6.0
        //.EQU	bias_EE0=              20				;8.0
        //.EQU	deadBand_EE0=	        4				;8.0
        //.EQU	maxOutput_EE0=	      130				;8.0
        //.EQU	maxErrorShutOff_EE0= 2000				;12.0
        //.EQU	CalcInterval_EE0=	    2          <<4	;3.0 from 0 to 7
        //.EQU	IsCmdDirStep_EE0=	    1          <<7	;1.0 0 or 1
        //.EQU	Address_FF1_EE0= (FF1_EE0&0b1111111111110000)|\
        //                     (Address_EE0&0b0000000000001111)
        //.EQU	maxErrorShutOffL_EE0= low(maxErrorShutOff_EE0)
        //.EQU	maxErrorShutOffH_EE0= high(maxErrorShutOff_EE0)&0b00001111
        //.EQU	config_maxErrorShutOff2_EE0=maxErrorShutOffH_EE0|\
        //                    CalcInterval_EE0|IsCmdDirStep_EE0
        //.EQU	controlSum_EE0=low(Pgain_EE0)+high(Pgain_EE0)+\
        //        low(Igain_EE0)+high(Igain_EE0)+\
        //        low(Dgain_EE0)+high(Dgain_EE0)+\
        //        low(Address_FF1_EE0)+high(Address_FF1_EE0)+\
        //        maxI_EE0+CmdMultiplier_EE0+bias_EE0+deadBand_EE0+\
        //        maxOutput_EE0+maxErrorShutOffL_EE0+\
        //        config_maxErrorShutOff2_EE0
        //;Bank0
        //.DW Pgain_EE0, Igain_EE0, Dgain_EE0
        //.DB maxI_EE0, CmdMultiplier_EE0, bias_EE0, deadBand_EE0
        //.DB maxOutput_EE0, maxErrorShutOffL_EE0
        //.DW Address_FF1_EE0
        //.DB config_maxErrorShutOff2_EE0, controlSum_EE0

        public byte[] Bank;
        public EepromBank()
        {
            Bank = new byte[16];
            this.IsCmdDirStep = true;
        }
        private byte low(double d)
        {
            int val = Convert.ToInt32(d);
            return Convert.ToByte(val & 0x00FF);
        }
        private byte high(double d)
        {
            int val = Convert.ToInt32(d);
            return Convert.ToByte(val >> 8);
        }
        public double Pgain
        {
            get
            {
                short valL = (short)(Bank[0]);
                short val = (short) (valL|(short)(Bank[1] << 8));
                return Convert.ToDouble(val)/256.0; 
            }
            set
            {
                Bank[0] = low(value * 256.0);
                Bank[1] = high(value * 256.0);
            }
        }
        
        public double Igain
        {
            get
            {
                short valL = (short)(Bank[2]);
                short val = (short)(valL | (short)(Bank[3] << 8));
                return Convert.ToDouble(val) / 65536.0;
            }
            set
            {
                Bank[2] = low(value * 65536.0);
                Bank[3] = high(value * 65536.0);
            }
        }
        public double Dgain
        {
            get
            {
                short valL = (short)(Bank[4]);
                short val = (short)(valL | (short)(Bank[5] << 8));
                return Convert.ToDouble(val) / 256.0;
            }
            set
            {
                Bank[4] = low(value * 256.0);
                Bank[5] = high(value * 256.0);
            }
        }

        public double maxI
        {
            get
            {
                return Convert.ToDouble(Bank[6]);
            }
            set
            {
                Bank[6] = Convert.ToByte(value);
            }
        }
        public double CmdMultiplier
        {
            get
            {
                return Convert.ToDouble(Bank[7]);
            }
            set
            {
                Bank[7] = Convert.ToByte(value);
            }
        }
        public double bias
        {
            get
            {
                return Convert.ToDouble(Bank[8]);
            }
            set
            {
                Bank[8] = Convert.ToByte(value);
            }
        }
        public double deadBand
        {
            get
            {
                return Convert.ToDouble(Bank[9]);
            }
            set
            {
                Bank[9] = Convert.ToByte(value);
            }
        }
        public double maxOutput
        {
            get
            {
                return 2.0*Convert.ToDouble(Bank[10]);
            }
            set
            {
                Bank[10] = Convert.ToByte(value/2.0);
            }
        }
        public double maxErrorShutOff
        {
            get
            {
                short maxErrorShutOffL = (short)(Bank[11]);
                short maxErrorShutOffH = (short)((Bank[14] & 0x0F) << 8);
                return Convert.ToDouble((short)(maxErrorShutOffL | maxErrorShutOffH));
            }
            set
            {
                Bank[11] = low(value);
                Bank[14] = (byte)((Bank[14] & 0xF0) | (high(value) & (byte)0x0F));
            }
        }
        public double FF1
        {
            get
            {
                short FF1L = (short)(Bank[12] & 0xF0);
                short FF1H = (short)((Bank[13]) << 8);
                return Convert.ToDouble((short)(FF1L | FF1H)) / 256.0;
            }
            set
            {
                Bank[12] = (byte)((Bank[12] & 0x0F) | (low(value * 256.0) & 0xF0));
                Bank[13] = high(value * 256.0);
            }
        }
        public double Address
        {
            get
            {
                return Convert.ToDouble(Bank[12] & 0x0F);
            }
            set
            {
                Bank[12] = (byte)((Bank[12] & 0xF0) | (low(value) & 0x0F));
            }
        }
        public double CalcInterval
        {
            get
            {
                return Convert.ToDouble((Bank[14] & 0x70) >> 4);
            }
            set
            {
                Bank[14] = (byte)((Bank[14] & 0x8F) | ((low(value) << 4) & 0x70));
            }
        }
        public bool IsCmdDirStep
        {
            get
            {
                return ((Bank[14] & 0x80) > 0);
            }
            set
            {
                Bank[14] = (byte)((Bank[14] & 0x7F) | (value ? 0x80 : 0x00));
            }
        }
        public byte CalculateCSum()
        {
            uint sum = 0;
            for (int i = 0; i < 15; i++)
                sum += Bank[i];
            Bank[15] = (byte)(sum & 0xFF);
            return Bank[15];
        }
    }
}
